﻿using System;
using Volo.Abp.Validation.StringValues;

namespace Xms.Abp.Validation.StringValues;

[Serializable]
[ValueValidator("TIME")]
public class TimeValueValidator : ValueValidatorBase
{
    public TimeSpan MinValue
    {
        get => (this["MinValue"] ?? TimeSpan.Parse("00:00:00")).To<TimeSpan>();
        set => this["MinValue"] = value;
    }

    public TimeSpan MaxValue
    {
        get => (this["MaxValue"] ?? TimeSpan.Parse("1.00:00:00")).To<TimeSpan>();
        set => this["MaxValue"] = value;
    }

    public TimeValueValidator()
    {
        MinValue = TimeSpan.MinValue;
        MaxValue = TimeSpan.FromDays(1);
    }

    public TimeValueValidator(TimeSpan? minValue = null, TimeSpan? maxValue = null)
    {
        MinValue = minValue ?? TimeSpan.MinValue;
        MaxValue = maxValue ?? TimeSpan.FromDays(1);
        if (MinValue > MaxValue)
        {
            throw new ArgumentException("Parameter 'minValue' cannot be less than parameter 'maxValue'.");
        }
    }

    public override bool IsValid(object value)
    {
        if (value == null)
        {
            return false;
        }

        if (value is TimeSpan timeSpan)
        {
            return IsValidInternal(timeSpan);
        }

        if (value is string str)
        {
            if (TimeSpan.TryParse(str, out var dateTimeValue))
            {
                return IsValidInternal(dateTimeValue);
            }
        }

        return false;
    }

    protected virtual bool IsValidInternal(TimeSpan value)
    {
        return value.IsBetween(MinValue, MaxValue);
    }
}
